
#pragma once

#include <stdint.h>

namespace incremental_crc {

    uint16_t modbus_crc16_hl(uint8_t data, uint8_t last_crc_h, uint8_t last_crc_l) {
        extern uint8_t modbus_crc16_table_h[256];
        extern uint8_t modbus_crc16_table_l[256];

        uint_fast16_t index = last_crc_h ^ data;
        last_crc_h = last_crc_l ^ modbus_crc16_table_h[index];
        last_crc_l = modbus_crc16_table_l[index];
        return static_cast<uint16_t>(last_crc_h << 8) + last_crc_l;
    }
    
    uint16_t modbus_crc16(uint8_t data, uint16_t last_crc) {
        uint_fast8_t h = static_cast<uint_fast8_t>(last_crc >> 8);
        uint_fast8_t l = static_cast<uint_fast8_t>(last_crc & 0x00ff);
        return modbus_crc16_hl(data, h, l);
    }

}